
import 'dart:developer' as developer;
import 'dart:io';

import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_audio_recorder2/flutter_audio_recorder2.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

///媒体工具，负责申请权限，选照片，拍照，录音，播放语音
class MediaUtil {
  FlutterSound flutterSound = new FlutterSound();
  FlutterSoundPlayer myPlayer = FlutterSoundPlayer();

  String pageName = "example.MediaUtil";

  FlutterAudioRecorder2? _recorder;

  MediaUtil._privateConstructor();
  static MediaUtil? _instance = MediaUtil._privateConstructor();
  static MediaUtil? get instance { return _instance;}

  static MediaUtil? getInstance() {
    if (_instance == null) {
      _instance = MediaUtil._privateConstructor();
    }
    return _instance;
  }

  //请求权限：相册，相机，麦克风
  void requestPermissions() async {
    Map<Permission, PermissionStatus> statuses = await [
      Permission.photos,
      Permission.camera,
      Permission.microphone,
      Permission.storage
    ].request();
    for (var status in statuses.keys) {
      developer.log(status.toString() + "：" + statuses[status].toString(), name: pageName);
    }
  }

  //开始录音
  void startRecordAudio() async {
    developer.log("debug 准备录音并检查权限", name: pageName);
    bool hasPermission = await  FlutterAudioRecorder2.hasPermissions ?? false;
    if (hasPermission) {
      developer.log("debug 录音权限已开启", name: pageName);
      Directory tempDir = await getTemporaryDirectory();
      String tempPath = tempDir.path + "/" + DateTime.now().millisecondsSinceEpoch.toString() + ".aac";
      _recorder = FlutterAudioRecorder2(tempPath, audioFormat: AudioFormat.AAC); // or AudioFormat.WAV
      await _recorder!.initialized;
      await _recorder!.start();
      developer.log("debug 开始录音", name: pageName);
    } else {
      BotToast.showText(text: "录音权限未开启");
    }
  }

  //录音结束，通过 finished 返回本地路径和语音时长，注：Android 必须要加 file:// 头
  void stopRecordAudio(Function(String? path, int duration) finished) async {
    var result = await _recorder!.stop();
    developer.log( "暂停 recording: path = ${result!.path}，duration = ${result.duration}", name: pageName);
    developer.log("暂停 recording: duration = ${result.duration}",
        name: pageName);
    if (result.duration!.inSeconds > 0) {
      String? path = result.path;
      if (path == null) {
        if (finished != null) {
          finished(null, 0);
        }
      }
      if (TargetPlatform.android == defaultTargetPlatform) {
        path = "file://" + path!;
      }
      if (finished != null) {
        finished(path!, result.duration!.inSeconds);
      }
    } else {
      BotToast.showText(text: "说话时间太短");
    }
  }

  //播放语音
  void startPlayAudio(String? path) async{
    if(!myPlayer.isOpen()){ // 初始化
      await myPlayer.openAudioSession().then( (v){

      } );
    }
    if (myPlayer.isPlaying) {
      stopPlayAudio();
    }else{
      myPlayer.startPlayer(fromURI:path );
    }
  }

  //停止播放语音
  void stopPlayAudio() {
    myPlayer.stopPlayer();
  }

  // 销毁音频播放器
  void closeAudioSession(){
    if(myPlayer.isOpen())myPlayer.closeAudioSession();
  }

  String getCorrectedLocalPath(String localPath) {
    String path = localPath;
    //Android 本地路径需要删除 file:// 才能被 File 对象识别
    if (TargetPlatform.android == defaultTargetPlatform) {
      path = localPath.replaceFirst("file://", "");
    }
    return path;
  }


}
